package com.xiguaji.tiktok.task.blogger.event;

import com.google.common.eventbus.AllowConcurrentEvents;
import com.google.common.eventbus.Subscribe;
import com.gugee.tiktok.common.model.dal.blogger.BloggerLogRepository;
import com.gugee.tiktok.common.model.dal.blogger.BloggerRepository;
import com.gugee.tiktok.common.model.dto.SlimBloggerDto;
import com.gugee.tiktok.common.model.mysql.BloggerLog;
import com.xiguaji.boot.eventbus.Event;
import com.xiguaji.boot.eventbus.EventBusTemplate;
import com.xiguaji.boot.eventbus.IEventListener;

import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;

import com.xiguaji.tiktok.task.core.ScheduleTemplate;
import io.netty.util.concurrent.DefaultThreadFactory;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Optional;

import org.springframework.util.CollectionUtils;

@Component
public class FetchFollowerEventListener implements IEventListener<FetchFollowerEventListener.FetchFollowerEvent> {
    @Autowired
    BloggerLogRepository bloggerLogRepository;

    @Autowired
    BloggerRepository bloggerRepository;

    @Autowired
    @Lazy
    EventBusTemplate eventBusTemplate;

    @Override
    @Subscribe
    @AllowConcurrentEvents
    public void handle(FetchFollowerEvent event) {
        run(event);
    }

    private void run(FetchFollowerEvent event) {
        int bloggerLogType = event.resetWhenFetchNothing ?
                BloggerLog.BloggerLogType.FETCH_FOLLOWER_LOOP.getValue() : BloggerLog.BloggerLogType.FETCH_NEW_FOLLOWER.getValue();

        Optional<BloggerLog> bloggerLogOptional = bloggerLogRepository.findByLogType(bloggerLogType);
        BloggerLog bloggerLog;

        long id = 0;
        if (bloggerLogOptional.isPresent()) {
            id = bloggerLogOptional.get().getCurrentBloggerId();
            bloggerLog = bloggerLogOptional.get();
        } else {
            bloggerLog = new BloggerLog();
            bloggerLog.setLogType(bloggerLogType);
            bloggerLog.setExtValue("");
            bloggerLog.setCreateBy(event.getSource());
            bloggerLog.setUpdateBy(event.getSource());
        }

        List<SlimBloggerDto> bloggers = bloggerRepository.findSlimBloggersByIdAndCount(id, 20);
        if (CollectionUtils.isEmpty(bloggers)) {
            if (event.resetWhenFetchNothing) {
                bloggerLog.setCurrentBloggerId(0);
                bloggerLogRepository.save(bloggerLog);
            }
            return;
        }

        bloggerLog.setCurrentBloggerId(bloggers.get(bloggers.size() - 1).getId());
        bloggerLogRepository.save(bloggerLog);

        var saveBloggerEvent = new SaveBloggerFollowerEventListener.SaveBloggerFollowerEvent(event,
                bloggers.stream().map(SlimBloggerDto::getUid).collect(Collectors.toList()));
        eventBusTemplate.post(saveBloggerEvent);
    }

    public static class FetchFollowerEvent extends Event {
        public FetchFollowerEvent(boolean resetWhenFetchNothing) {
            super("FetchFollower");
            this.resetWhenFetchNothing = resetWhenFetchNothing;
        }

        /**
         * false 获取不到最新的数据时候时候等待，有新数据才执行
         * true 获取不到最新数据的时候重置，再从头开始更新
         */
        private boolean resetWhenFetchNothing;
    }
}
